﻿static char *tregist_id = 
	"@(#)Copyright (C) gaoguangtao 2008-2050   tregist.cpp	Ver2.06";

//注册表操作类源文件
/* ========================================================================
	Project  Name			: Win32 Lightweight  Class Library Test
	Module Name				: Registry Class
	Create					: 2008-02-20(Sat)
    Update					: 2008-02-14(Wed)
	Copyright				: gaoguangtao
	Reference				: 
	======================================================================== */

#include <stdio.h>
#include "tlib.h"

TRegistry::TRegistry(LPCSTR company, LPSTR appName)
{
	this->openCnt = 0;

	ChangeApp(company, appName);
}

TRegistry::TRegistry(HKEY top_key)
{
	this->topKey = top_key;
	this->openCnt = 0;
}

TRegistry::~TRegistry(void)
{
	while (this->openCnt > 0)
	{
		CloseKey();
	}
}

BOOL TRegistry::ChangeApp(LPCSTR company, LPSTR appName)
{
	while (this->openCnt > 0)
	{
		CloseKey();
	}

	this->topKey = HKEY_CURRENT_USER;

	char	buf[100];
	wsprintf(buf, "software\\%s", company);
	
	if (appName != NULL && *appName)
	{
		wsprintf(buf + strlen(buf), "\\%s", appName);
	}

	return CreateKey(buf);
}

void TRegistry::ChangeTopKey(HKEY top_key)
{
	while (this->openCnt > 0)
	{
		CloseKey();
	}

	this->topKey = top_key;
}

BOOL TRegistry::OpenKey(LPCSTR subKey, BOOL createFlg)
{
	HKEY parentKey = (openCnt == 0 ? topKey : hKey[openCnt -1]);

	if (this->openCnt >= MAX_KEYARRAY)
	{
		return	FALSE;
	}

	DWORD tmp;

	long returnCode = 0;
	if (createFlg)
	{
		returnCode = ::RegCreateKeyEx(parentKey, 
			                          subKey, 
									  0, 
									  NULL, 
									  REG_OPTION_NON_VOLATILE, 
									  KEY_ALL_ACCESS, 
									  NULL, 
									  &hKey[openCnt], 
									  &tmp) ;
	}
	else
	{
		returnCode = ::RegOpenKeyEx(parentKey, 
			                        subKey, 
									0, 
									KEY_ALL_ACCESS, 
									&hKey[openCnt]);
	}

	if (returnCode == ERROR_SUCCESS)
	{
		return	openCnt++, TRUE;
	}
	else
	{
		return FALSE;
	}
}

BOOL TRegistry::CloseKey(void)
{
	if (this->openCnt <= 0)
	{
		return FALSE;
	}

	::RegCloseKey(hKey[--openCnt]);

	return TRUE;
}

BOOL TRegistry::GetInt(LPCSTR subKey, int *val)
{
	long tmp_val;

	if (GetLong(subKey, &tmp_val) == FALSE)
	{
		return	FALSE;
	}
	
	*val = (int)tmp_val;

	return TRUE;
}

BOOL TRegistry::SetInt(LPCSTR subKey, int val)
{
	return SetLong(subKey, (long)val);
}

BOOL TRegistry::GetLong(LPCSTR subKey, long *val)
{
	DWORD type = REG_DWORD;
	DWORD dw_size = sizeof(long);

	long errorCode = ::RegQueryValueEx(hKey[openCnt -1], 
		                               subKey, 
									   0, 
									   &type, 
									   (BYTE *)val, 
									   &dw_size);
	if (errorCode == ERROR_SUCCESS)
	{
		return TRUE;
	}

	char	buf[100];
	long	size = sizeof(buf);

	errorCode = ::RegQueryValue(hKey[openCnt -1], 
		                        subKey, 
								buf, 
								&size);

	if (errorCode != ERROR_SUCCESS)
	{
		return	FALSE;
	}

	*val = atol(buf);

	return TRUE;
}

BOOL TRegistry::SetLong(LPCSTR subKey, long val)
{
	long errorCode =  ::RegSetValueEx(hKey[openCnt -1], 
		                              subKey,
									  0, 
									  REG_DWORD, 
									  (const BYTE *)&val, 
									  sizeof(val));

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::GetStr(LPCSTR subKey, LPSTR str, int size)
{
	DWORD type = REG_SZ;
	
	if (::RegQueryValueEx(hKey[openCnt -1], subKey, 0, &type, (BYTE *)str, (LPDWORD)&size) == ERROR_SUCCESS)
	{
		return TRUE;
	}

	return	::RegQueryValue(hKey[openCnt -1], subKey, str, (LPLONG)&size) == ERROR_SUCCESS;
}

BOOL TRegistry::SetStr(LPCSTR subKey, LPCSTR str)
{
	long errorCode = ::RegSetValueEx(hKey[openCnt -1], 
		                             subKey, 
		                             0, 
		                             REG_SZ, 
		                             (const BYTE *)str, 
		                             strlen(str) +1);
	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::GetByte(LPCSTR subKey, BYTE *data, int *size)
{
	DWORD type = REG_BINARY;

	long errorCode = ::RegQueryValueEx(hKey[openCnt -1], 
		                               subKey, 
									   0, 
									   &type, 
									   (BYTE *)data, 
									   (LPDWORD)size);
	
	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::SetByte(LPCSTR subKey, const BYTE *data, int size)
{
	long errorCode = ::RegSetValueEx(hKey[openCnt -1], 
		                             subKey, 
									 0, 
									 REG_BINARY, 
									 data, 
									 size);

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::DeleteKey(LPCSTR subKey)
{
	long errorCode = ::RegDeleteKey(hKey[openCnt -1], subKey);

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::DeleteValue(LPCSTR subValue)
{
	long errorCode = ::RegDeleteValue(hKey[openCnt -1], subValue);

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::EnumKey(DWORD cnt, LPSTR buf, int size)
{
	long errorCode = ::RegEnumKeyEx(hKey[openCnt -1], 
		                            cnt, 
									buf, 
									(LPDWORD)&size, 
									0, 
									0, 
									0, 
									0);

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::EnumValue(DWORD cnt, LPSTR buf, int size, DWORD *type)
{
	long errorCode = ::RegEnumValue(hKey[openCnt -1], 
		                            cnt, 
									buf, 
									(LPDWORD)&size, 
									0, 
									type, 
									0, 
									0);

	return errorCode == ERROR_SUCCESS;
}

BOOL TRegistry::DeleteChildTree(LPSTR subKey)
{
	char	buf[100];
	BOOL	ret = TRUE;

	if (subKey != NULL && OpenKey(subKey) != TRUE)
	{
		return FALSE;
	}

	while (EnumKey(0, buf, sizeof(buf)))
	{
		if ((ret = DeleteChildTree(buf)) != TRUE)
		{
			break;
		}
	}

	if (subKey != NULL)
	{
		CloseKey();
		ret = DeleteKey(subKey) ? ret : FALSE;
	}
	else 
	{
		while (EnumValue(0, buf, sizeof(buf)))
		{
			if (DeleteValue(buf) != TRUE)
			{
				ret = FALSE;

				break;
			}
		}
	}

	return	ret;
}